﻿/*
MIT License

Copyright (c) <2020> <lihp1603:https://gitee.com/lihaiping1603>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include <stdio.h>


#define __STDC_CONSTANT_MACROS

#ifdef __cplusplus
extern "C" {
#endif
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>  

/*Include ffmpeg header file*/
#include "libavformat/avformat.h"
#include "libavutil/log.h"
#include "libavutil/time.h"
#include <process.h>

#pragma comment(lib,"avformat.lib")
#pragma comment(lib,"avutil.lib")
#ifdef __cplusplus
}
#endif



#ifdef WIN32
#define snprintf _snprintf
#define getpid   _getpid
#define inline _inline
#endif

 
void log_localtime(void* avcl, int level, const char *fmt,...){
	va_list vl;
	va_start(vl, fmt);
	av_log_default_callback(avcl,level,fmt,vl);
	va_end(vl);
}

void log_time(void* avcl,int level){
	//这里获取到的为微秒
	int64_t now = av_gettime();
	struct timeval tp;
	tp.tv_usec = (long) ((now%10000000));
	now = now/1000000;
	tp.tv_sec =now;
	struct tm* tm=NULL; //转换一下，转换为本地时间
	if ((tm = localtime((const time_t *)(&(now)))) == NULL) {
		return ;
	}
	//格式化
	log_localtime(avcl,level,"[%d-%02d-%02d %02d:%02d:%02d.%03d]",
		1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, (int)(tp.tv_usec / 1000));
	return ;
}

//第二种方式实现
void log_callback2(void* avcl, int level, const char *fmt, va_list vl){
	char buffer_timer[4096]={0};
	//这里获取到的为微秒
	int64_t now = av_gettime();
	struct timeval tp;
	tp.tv_usec = (long) ((now%1000000));
	now = now/1000000;
	tp.tv_sec =now;
	struct tm* tm=NULL; //转换一下，转换为本地时间
	if ((tm = localtime((const time_t *)(&(now)))) == NULL) {
		av_log_default_callback(avcl,level,fmt,vl);
		return ;
	}
	//格式化时间
	int writen=snprintf(buffer_timer,sizeof(buffer_timer),"[%d-%02d-%02d %02d:%02d:%02d.%03d][%d]%s",
		1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, (int)(tp.tv_usec / 1000),getpid(),fmt);
	if (writen<=0||writen==sizeof(buffer_timer))//防止超过或者未输入进去
	{
		av_log_default_callback(avcl,level,fmt,vl);
		return ;
	}
	//int buffer_timer_size = strlen(fmt)+128;
	//char *buffer_timer = (char*)av_mallocz(buffer_timer_size);
	//int wirten=_snprintf(buffer_timer,buffer_timer_size,"[%d-%02d-%02d %02d:%02d:%02d.%03d]%s",1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, (int)(tp.tv_usec / 1000),fmt);

	//继续使用默认的回调函数
	av_log_default_callback(avcl,level,buffer_timer,vl);
	return ;
}


void log_callback(void* avcl, int level, const char *fmt, va_list vl){
	//
	log_callback2(avcl,level,fmt,vl);
	////打印出当前的时间信息
	//log_time(avcl,level);
	////继续使用默认的回调函数
	//av_log_default_callback(avcl,level,fmt,vl);
}


int main (int argc, const char * argv[])
{
    AVFormatContext *pFormatCtx=NULL;//保存需要读入的文件格式信息,比如流的个数及流数据
	int ret=0,k=0;
	const char* filename="e:/video/1080_BXJG.mp4";
	
	//设置日志打印级别
	 av_log_set_level(AV_LOG_TRACE);
	// 自定义日志打印回调
	av_log_set_callback(log_callback);

	if((k=avformat_open_input(&pFormatCtx, filename, NULL, NULL))!=0)
	{
		printf("error:%d\n",k);
        return -1; // Couldn't open file
	}

	av_log(NULL,AV_LOG_INFO,"hello\n");
	av_log(pFormatCtx,AV_LOG_INFO,"print ffmpeg log\n");
	av_log(NULL,AV_LOG_INFO,"EOF:%d\n",AVERROR_EOF);
	av_log(NULL,AV_LOG_INFO,"EAGAIN:%d\n",AVERROR(EAGAIN));
	av_log(NULL,AV_LOG_INFO,"EIO:%d\n",AVERROR(EIO));
	av_log(NULL,AV_LOG_INFO,"EXIT:%d\n",AVERROR_EXIT);
	
	if (pFormatCtx){
		avformat_close_input(&pFormatCtx);
		pFormatCtx=NULL;
	}
	system("pause");
	return 0;
}
 
